docker 指南

docker 指南

docker 使应用部署更加轻量,可移植,可扩展,更好的环境隔离也更大程度地避免了生产环境与测试环境不一致的巨大尴尬。

由于 docker 轻便可移植的特点也极大促进了 CI/CD 的发展。

image-20230421170616756

  • docker client: 命令行工具
  • Docker host : 宿主机, Docker Daemon的运行环境服务器
  • docker dameon: docker 的守护进程,docker client通过命令行与docker daemon交互
  • image: 镜像,可以理解为一个容器的模板,通过一个镜像可以创建多个容器
  • container: 最小型的一个操作系统环境,可以对各种服务以及应用容器化,是镜像的运行实例
  • registry: 镜像仓库,存储大量镜像,可以从镜像仓库拉取和推送镜像

Docker 安装

image-20230421154935226

image-20230421155022894

底层原理

docker 底层使用了一些 linux 内核的特性,大概有 namespacecgroupsufs

Namespace

docker 使用 linux namespace 构建隔离的环境,它由一下的namespace组成

  • pid : 隔离进程
  • net : 隔离网络
  • Ipc :隔离ipc
  • mnt :隔离文件系统挂载
  • uts :隔离hostname
  • user:隔离uid/gid

Control groups

也叫 cgroups,限制资源配额,比如某个容器只能使用 100M 内存

Union file systems

UnionFS 是一种分层、轻量级并且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加。docker 的镜像与容器就是分层存储,可用的存储引擎有 aufsoverlay 等。

镜像

镜像是一份用来创造容器的配置文件,而容器可以视作最小型的一个操作系统。

docker 的镜像和容器都使用了 unionFS 做分层存储,镜像作为只读层是共享的,而容器在镜像之上附加了一层可写层,最大程度地减少了空间的浪费

镜像仓库与拉取

大部分时候,我们不需要自己构建镜像,我们可以在官方镜像仓库 Docker Hub (opens new window)拉取镜像。

可以简单使用命令 docker pull 拉取镜像。

拉取镜像后可以使用 docker inspect 查看镜像信息,如配置及环境变量等。

1
2
3
4
5
6
7
8
9
10
11
# 加入拉取一个 node:alpine 的镜像
$ docker pull node:alpine

# 查看镜像信息
$ docker inspect node:alpine

# 列出所有镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
with-docker-multi-env-development latest 634d254e2057 2 days ago 146MB
simaple-app latest 20afeb439c58 3 days ago 146MB

构建镜像与发布

但并不是所有的镜像都可以在镜像仓库中找到,另外我们也需要为我们自己的业务应用去构建镜像。

使用 docker build 构建镜像,docker build 会使用当前目录的 Dockerfile 构建镜像

1
2
3
# -t 指定镜像以及版本号
# .: 指当前路径
$ docker build -t simple-app .

当构建镜像成功后可以使用 docker push 推送到镜像仓库。

Dockerfile命令简述

FROM

基于一个旧有的基础镜像,格式如下。

1
2
3
4
5
6
7
FROM <image> [AS <name>]

# 在多阶段构建时会用到
FROM <image>[:<tag>] [AS <name>]

FROM node:16-alpine
FROM nginx:alpine

而以上所述的 node 与 nginx 基础镜像可在Docker Hub (opens new window)中找到。

需要了解常用的 alpinenodenginx 基础镜像。

ADD

把宿主机的文件或目录加入到镜像的文件系统中。

1
2
3
ADD [--chown=<user>:<group>] <src>... <dest>

ADD . /code

RUN

在镜像中执行命令,由于 ufs 的文件系统,它会在当前镜像的顶层新增一层。

1
2
3
RUN <command>

RUN npm run build

CMD

指定容器如何启动。

一个 Dockerfile 中只允许有一个 CMD

1
2
3
4
5
6
7
8
9
10
# exec form, this is the preferred form
CMD ["executable","param1","param2"]

# as default parameters to ENTRYPOINT
CMD ["param1","param2"]

# shell form
CMD command param1 param2

CMD npm start

容器

镜像与容器的关系,类似于代码与进程的关系。

  • docker run 创建容器
  • docker stop 停止容器
  • docker rm 删除容器

创建容器

基于 nginx 镜像创建一个最简单的容器:启动一个最简单的 http 服务

使用 docker run 来启动容器,docker ps 查看容器启动状态

1
2
3
4
# 启动 nginx 容器,并在本地 8888 端口进行访问
$ docker run --rm -it --name nginx -p 8888:80 nginx:alpine

$ docker ps -l
  • --rm:当停止容器时自动清楚容器
  • -it:可交互式、赋予 tty 的方式
  • --name:为容器指定名称
  • -p host-port:container-port:宿主机与容器端口映射,方便容器对外提供服务
  • nginx:alpine:基于该基础镜像创建容器

容器管理

docker ps 列出所有容器

1
2
3
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4a64e4bc644 with-docker-multi-env-development "docker-entrypoint.s…" 2 days ago Up 3 seconds 0.0.0.0:3001->3000/tcp development-with-docker-multi-env-development-1

docker port 查看容器端口映射

1
2
$  docker port a4a64e4bc644
3000/tcp -> 0.0.0.0:3001

docker stats 查看容器资源占用

1
2
3
$ docker stats a4a64e4bc644
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a4a64e4bc644 development-with-docker-multi-env-development-1 0.00% 62.01MiB / 7.667GiB 0.79% 2.47kB / 7.58kB 65.9MB / 0B 7
感谢你的打赏哦!